package pb_error

import (
	"context"
	"errors"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"payme3000/framework/errorx"
)

// PbError 与proto错误码对应的错误
type PbError struct {
	code int32 // 错误码, 必须是pb的枚举类型
}

func (e *PbError) Error() string {
	return fmt.Sprintf("%d", e.code)
}

func (e *PbError) Code() int32 {
	if e == nil {
		return 0
	}

	return e.code
}

// New 构建proto错误, 不打印错误日志
func New(code int32) *PbError {
	err := &PbError{
		code: code,
	}

	return err
}

// Trace 构建proto错误, 打印日志但不是错误级别
func Trace(ctx context.Context, code int32) *PbError {
	err := New(code)

	var _code error
	if errors.As(err, &_code) {
		logx.WithContext(ctx).WithCallerSkip(1).Infof("pb error: %s", _code.Error())
	}

	return err
}

// Error 构建proto错误, 打印错误日志但不打印调用栈
func Error(ctx context.Context, code int32) *PbError {
	err := New(code)

	var _code error
	if errors.As(err, &_code) {
		logx.WithContext(ctx).WithCallerSkip(1).Errorf("pb error: %s", _code.Error())
	}

	return err
}

// Stack 构建proto错误, 打印错误日志和调用栈
func Stack(ctx context.Context, code int32) *PbError {
	err := New(code)

	var _code error
	if errors.As(err, &_code) {
		errorx.Catch(ctx, _code, 2)
	}

	return err
}
